<?php
class SessionData {

    public static $SESSION_KEY = 'application.data';
    
    private $id; // object instance identifier

    private $authAdmin;
    private $authUser;
    private $userSubstitute;
    private $authOrg;
    private $authOrgRole; /* auth::$ORG_ROLE_REPRESENTATIVE or auth::$ORG_ROLE_ORGANIZER */
    private $seminarWizardData;
    private $viseminWizardData;
    private $seminarAccountsData;
    private $registrationWizardData;
    private $viregWizardData;
    private $seminarAccomodationData;
    private $karmayogaAssignmentData;
    private $foreignPoliceExport;
    private $messages;
    private $lastException;

    private $navigationMarkList = array();

    public $viRegistration;

    private $searchCriteria = array();
    public $listOrders = array();

    private $properties = array();

    private $formIdList = array();
    
    private static $instance;
    
    private $receptionRegistrationData;

    /**
     * @return SessionData
     */
    public static function instance() {
        if (! self::$instance) {
            self::$instance = $_SESSION[SessionData::$SESSION_KEY];
            if (! self::$instance) {
                self::$instance = new SessionData();
                $_SESSION[SessionData::$SESSION_KEY] = self::$instance;
            }
        }
        return self::$instance;
    }

    public static function reset() {
        self::$instance = new SessionData();
        $_SESSION[SessionData::$SESSION_KEY] = self::$instance;
    }

    public function  __construct() {
        $this->id = rand(1000, 1000000);
    }

    public function clearUserSpaceData() {
        $this->viregWizardData = NULL;
        $this->registrationWizardData = NULL;
    }

    public function getAuthAdmin() {
        return $this->authAdmin;
    }
    public function setAuthAdmin($authAdmin) {
        $this->authAdmin = $authAdmin;
    }

    public function getAuthUser($field=null) {
    	if ($field) {
    		return $this->authUser[$field];
    	}
        return $this->authUser;
    }
    public function setAuthUser($authUser) {
        $this->authUser = $authUser;
    }

    public function setAuthOrg($authOrg) {
        $this->authOrg = $authOrg;
    }
    public function getAuthOrg($field=null) {
    	if ($field) {
    		return $this->authOrg[$field];
    	}
    	return $this->authOrg;
    }
    
    public function setAuthOrgRole($authOrgRole) {
        $this->authOrgRole = $authOrgRole;
    }
    public function getAuthOrgRole() {
        return $this->authOrgRole;
    }

    // Seminar wizard
    public function getSeminarWizardData() {
        if (! $this->seminarWizardData) {
            $this->seminarWizardData = new SeminarWizardData();
        }
        return $this->seminarWizardData;
    }
    public function setSeminarWizardData($seminarWizardData) {
        $this->seminarWizardData = $seminarWizardData;
    }

    // Visemin wizard
    public function getViseminWizardData() {
        if (! $this->viseminWizardData) {
            $this->viseminWizardData = new ViseminWizardData();
        }
        return $this->viseminWizardData;
    }
    public function setViseminWizardData($viseminWizardData) {
        $this->viseminWizardData = $viseminWizardData;
    }

    // Registration wizard
    public function getRegistrationWizardData() {
        if (! $this->registrationWizardData) {
            $this->registrationWizardData = new RegistrationWizardData();
        }
        return $this->registrationWizardData;
    }
    public function setRegistrationWizardData($registrationWizardData) {
        $this->registrationWizardData = $registrationWizardData;
    }
    
    // Registration data
    public function getRegistrationData() {
        if (! $this->registrationData) {
            $this->registrationData = new RegistrationData();
        }
        return $this->registrationData;
    }
    public function setRegistrationData($registrationData) {
        $this->registrationData = $registrationData;
    }
    
    // Reception registration data
    public function getReceptionRegistrationData() {
    	if (! $this->receptionRegistrationData) {
    		$this->receptionRegistrationData = new RegistrationData();
    	}
    	return $this->receptionRegistrationData;
    }
    public function setReceptionRegistrationData($receptionRegistrationData) {
    	$this->receptionRegistrationData = $receptionRegistrationData;
    }

    // Vireg wizard
    public function getViregWizardData() {
        return $this->viregWizardData;
    }
    public function setViregWizardData($viregWizardData) {
        $this->viregWizardData = $viregWizardData;
    }
    
    // Seminar wizard
    public function getSeminarAccountsData() {
        if (! $this->seminarAccountsData) {
            $this->seminarAccountsData = new SeminarAccountsData();
        }
        return $this->seminarAccountsData;
    }
    public function setSeminarAccountsData($seminarAccountsData) {
        $this->seminarAccountsData = $seminarAccountsData;
    }

    public function getMessages() {
        return $this->messages;
    }
    public function setMessages($messages) {
        $this->messages = $messages;
    }

    public function setSearchCriteria($formName, $criteria) {
        $this->searchCriteria[$formName] = $criteria;
    }
    public function getSearchCriteria($formName) {
        return $this->searchCriteria[$formName];
    }
    
	public function &getSeminarAccomodationData() {
        return $this->seminarAccomodationData;
    }
    public function setSeminarAccomodationData(&$seminarAccomodationData) {
        $this->seminarAccomodationData = $seminarAccomodationData;
    }
    
    public function &getKarmayogaAssignmentData() {
    	return $this->karmayogaAssignmentData;
    }
    public function setKarmayogaAssignmentData(&$karmayogaAssignmentData) {
    	$this->karmayogaAssignmentData = $karmayogaAssignmentData;
    }

    public function setListOrder($formName, $listOrder) {
        $this->listOrders[$formName] = $listOrder;
    }
    public function getListOrder($formName) {
        return $this->listOrders[$formName];
    }

    public function setLastException($lastException) {
        $this->lastException = $lastException;
    }
    public function getLastException() {
        return $this->lastException;
    }

    public function getUserSubstitute($field=null) {
    	if ($field) {
    		return $this->userSubstitute[$field];
    	}
    	return $this->userSubstitute;
    }
    public function setUserSubstitute($userSubstitute) {
        $this->userSubstitute = $userSubstitute;
    }

    public function getProperty($key) {
        return $this->properties[$key];
    }
    public function setProperty($key, $value) {
        $this->properties[$key] = $value;
    }

    public function getId() {
        return $this->id;
    }

    public function createFormId() {
        $formId = md5(rand(1, 100000000) . time());
        if (array_search($formId, $this->formIdList) !== FALSE) {
            return $this->createFormId();
        }
        array_push($this->formIdList, $formId);
        if (count($this->formIdList) > 256) {
            // Do not allow the array to grow too much.
            array_shift($this->formIdList);
        }
        return $formId;
    }
    public function checkAndRemoveFormId($formId) {
        $index = array_search($formId, $this->formIdList);
        if ($index === FALSE) {
            return FALSE;
        }
        unset($this->formIdList[$index]);
        return TRUE;
    }
    
    public function getForeignPoliceExportData() {
    	if (! $this->foreignPoliceExport) {
    		$this->foreignPoliceExport = new ForeignPoliceExportData();
    	}
    	return $this->foreignPoliceExport;
    }
    public function setForeignPoliceExportData($foreignPoliceExport) {
    	$this->foreignPoliceExport = $foreignPoliceExport;
    }

    public function addNavigationMark($mark) {
        $this->navigationMarkList[] = $mark;
        if (count($this->navigationMarkList) > 20) {
            array_shift($this->navigationMarkList);
        }
    }
    public function isFirstMarkPatternCloser($firstMark, $secondMark) {
        for ($i = count($this->navigationMarkList) - 1; $i >= 0; $i--) {
            $value = $this->navigationMarkList[$i];
            if (preg_match($firstMark, $value)) {
                return TRUE;
            }
            if (preg_match($secondMark, $value)) {
                return FALSE;
            }
        }
        return FALSE;
    }
}
